# -*- coding: utf-8 -*-
"""
Created on Thu Nov 19 14:50:34 2020

@author: weifeng.zhang
"""
import os
import json
import configparser
import importlib
from functools import lru_cache
from .aiuamabean import ModelBean,AlgorithmBean


class BaseAlgorithm:
      
    #缓存算法列表
    @lru_cache()
    def getAlgorithmlt(cls): 
        print("调用获取算法列表！")
        #算法模型存放的地址路径
        basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep + ".." +  os.sep + "models"
        cf = configparser.ConfigParser()
        #遍历文件夹
        algorithmLt = []
        for filename in os.listdir(basedir):
            if os.path.isdir(os.path.join(basedir,filename)):
                #读取配置文件
                algoritgnPath = os.path.join(basedir,filename)
                inipath = os.path.join(algoritgnPath,filename+".ini")
                if os.path.exists(inipath) :
                    #读取配置文件
                    cf.read(inipath,encoding='utf-8')
                    algorithmBean = AlgorithmBean( 
                        filename , #约定文件夹名称就是算法编码
                        cf.get("define", "algorithm_name"),
                        cf.get("define", "algorithm_desc"),
                        cf.get("define", "algorithm_doc"),
                        cf.get("define", "training_template"),
                        #cf.get("define", "training_methond"),
                        #cf.get("define", "call_method")
                    )
                    algorithmLt.append(algorithmBean)
        return algorithmLt
        
    #从算法中获取算法定义    
    def getAlgorithmByCode(self,algorithm_code: str,algorithmLt : list):    
        for algorithm in algorithmLt:
            if algorithm.algorithm_code == algorithm_code:
                return algorithm
        return None
        
    
    #创建模型相关信息
    def addModel(self,model : ModelBean):
        #获取工程目录
        basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep +".." + os.sep + "models"
        algorithmdir = basedir + os.sep + model.algorithm_code
        #模型定义存储文件
        models_file = algorithmdir + os.sep + "models.md"
        #追加文件输入
        f = open(models_file, "a+",encoding='utf8')
        f.write(json.dumps(model.__dict__,ensure_ascii=False)+"\n")
        f.close()
    
    #根据算法CODE 获取模型列表    
    def getModelltByAlgorithmCode(self,algorithm_code):
        models = []
        #获取工程目录
        basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep +".." + os.sep + "models"
        algorithmdir = basedir + os.sep + algorithm_code
        #模型定义存储文件
        models_file = algorithmdir + os.sep + "models.md"
        if os.path.exists(models_file):
            #按行读取文件信息
            with open(f"{models_file}",'r',encoding="utf8") as f:
                lt = f.readlines()
            f.close()
        
            for i in range(0, len(lt)):
                lt[i] = lt[i].rstrip('\n')
                print(lt[i])
                model = json.loads(lt[i])
                #model = json.loads(lt[i], object_hook=ModelBean)
                models.append(model)
        return models
    
    #根据算法CODE 和模型CODE  获取模型信息    
    def getModelByCode(self,algorithm_code,model_code):
        models = BaseAlgorithm.getModelltByAlgorithmCode(self,algorithm_code)
        print(len(models),model_code)
        if len(models) :
            for model in models :
                print(model['model_code'])
                if model['model_code'] == model_code:
                    print(model_code)
                    basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep +".." + os.sep + "models"
                    algorithmdir = basedir + os.sep + algorithm_code
                    modelmdir = algorithmdir + os.sep + model_code
                    training_file_path = modelmdir + os.sep + model['training_file']
                    model['model_base_dir'] = modelmdir
                    model['training_file_path'] = training_file_path
                    return model
            return None 
        else :
            return None

    
    #训练样本，需要参数为 模型名称，模型描述，样本地址
    def trainingModel(self,algorithmBean: AlgorithmBean,modeljson: json):
        exemodel = "models." + algorithmBean.algorithm_code + ".main"
        exe = importlib.import_module(exemodel)
        print(modeljson)
        return exe.trainingAlgorithm(modeljson)
        
    
    #调用模型，需要参数模型名称，模型参数
    def callModel(self,algorithmBean: AlgorithmBean,modeljson: json,params):
        exemodel = "models." + algorithmBean.algorithm_code + ".main"
        exe = importlib.import_module(exemodel)
        print(modeljson)
        return exe.callAlgorithm(modeljson,params)